import { createStore } from 'vuex'
import getters from './getters'

import permission from './modules/permission'
import user from './modules/user'
import app from './modules/app'

export interface State {
  user: typeof user.state
  permission: typeof permission.state
  app: typeof app.state
}

// type GetterFuncs = (typeof app.getters)

type CommitFuncs = (
  typeof app.mutations &
  typeof permission.mutations &
  typeof user.mutations
)

interface Commit {
  <T extends keyof CommitFuncs>(type: T, payload?: Parameters<CommitFuncs[T]>[1]): void
}

// dispatch 处理步骤同 commit
type DispatchFuncs = (
  typeof app.actions &
  typeof user.actions &
  typeof permission.actions

)
interface Dispatch {
  <T extends keyof DispatchFuncs>(type: T, payload?: Parameters<DispatchFuncs[T]>[1]): Promise<any>
}

export type ReturnGetters<T extends { [key: string]: (...args: any) => any; }> = {
  [P in keyof T]: ReturnType<T[P]>
}
type Getters = ReturnGetters<typeof getters>

export type RootStore = {
  state: State
  getters: Getters
  commit: Commit
  dispatch: Dispatch
}
type MyStore<T, U extends Partial<T>> = {
  [P in keyof T]: P extends keyof U ? U[P] : T[P]
}
const store = createStore({
  modules: {
    user,
    permission,
    app,
  },
  getters,
})

export default store as MyStore<typeof store, RootStore>
